package cn.liccshop.core.service.shopOrderInfo.controller;


import cn.liccshop.core.entity.*;
import cn.liccshop.core.proscenium.shopUser.service.IShopUserService;
import cn.liccshop.core.service.shopOrderGoods.service.IShopOrderGoodsService;
import cn.liccshop.core.service.shopOrderInfo.service.IShopOrderInfoService;
import cn.liccshop.core.service.shopOrderReturn.service.IShopOrderReturnService;
import cn.liccshop.core.service.shopTransaction.service.IShopTransactionService;
import cn.liccshop.core.utils.ObjectToOtherUtils;
import cn.liccshop.sys.cache.CommonCacheUtil;
import cn.liccshop.sys.constants.Constants;
import cn.liccshop.sys.entity.Result;
import cn.liccshop.sys.entity.UserElement;
import cn.liccshop.sys.exception.MySystemException;
import cn.liccshop.sys.utils.RandomNumberCode;
import cn.liccshop.sys.zhifubao.MyPay;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import cn.liccshop.sys.base.MyActionController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @description 订单信息基本表 前端控制器
 *
 * @author LiCC
 * @since 2019-05-13
 */
@RestController
@RequestMapping("/shopOrderInfo")
public class ShopOrderInfoController extends MyActionController<ShopOrderInfo> {

    @Autowired
    private IShopOrderInfoService liShopOrderInfoService;
    @Autowired
    private IShopOrderGoodsService iShopOrderGoodsService;
    @Autowired
    private IShopUserService userService;
    @Autowired
    private IShopOrderReturnService orderReturnService;
    @Autowired
    private IShopTransactionService transactionService;
    @Autowired
    private CommonCacheUtil cacheUtil;
    @Autowired
    private MyPay myPay;

    @Override
    protected IService<ShopOrderInfo> getLiService(){
        return liShopOrderInfoService;
    }

    /**
     * 消费者用户提交订单， 订单为待支付状态
     * @param map
     * @return
     */
    @RequestMapping("/addInfo")
    public Result addInfo(@RequestBody Map<String, Object> map) throws MySystemException {
        String userId = getUserInfoByToken().getUserId();
        if (StringUtils.isBlank(userId)){
            /** 用户未登录 **/
            throw new MySystemException("用户未登录", Constants.UNAUTHEN);
        }
        map.put("userId", userId);
        ShopOrderInfo shopOrderInfo = liShopOrderInfoService.addInfo(map);
        return shopOrderInfo!=null ? new Result().setCode(Constants.OK).setData(shopOrderInfo).setMessage("提交成功")
                : new Result().setCode(Constants.FAIL).setMessage("提交失败");
    }

    /**
     * 用户支付或者确认收货
     * @param map
     * @return
     * @throws MySystemException
     */
    @RequestMapping("/payOrReceive")
    public Result orderPayOrReceive(@RequestBody Map<String, Object> map) throws MySystemException {
        String orderId = ObjectToOtherUtils.toString(map.get("id"));
        Integer orderStatus = ObjectToOtherUtils.toInteger(map.get("orderStatus"));
        /** 订单状态前端已经修改 **/
        if (StringUtils.isBlank(orderId)||(!orderStatus.equals(Constants.ORDER_STATUS_DELIVER)&&!orderStatus.equals(Constants.ORDER_STATUS_COMMENT))){
            throw new MySystemException("参数异常", Constants.INVALID_PARM);
        }
        UserElement userElement = getUserInfoByToken();
        String userId = userElement==null?null:userElement.getUserId();
        if (StringUtils.isBlank(userId)){
            throw new MySystemException("用户未登录",Constants.UNAUTHEN);
        }
        ShopOrderInfo orderInfo = new ShopOrderInfo().setId(orderId).setOrderStatus(orderStatus).setUserId(userId);
        if (orderStatus.equals(Constants.ORDER_STATUS_DELIVER)){
            orderInfo.setPayTime(LocalDateTime.now());
        } else {
            orderInfo.setDeliveryTime(LocalDateTime.now());
        }
        /** 订单支付或收货 **/
        liShopOrderInfoService.orderPay(orderInfo);
        return new Result().setCode(Constants.OK).setData(orderInfo).setMessage("提交成功");
    }

    /***
     * 获取支付宝支付页面
     * @param map
     * @return
     * @throws MySystemException
     */
    @RequestMapping("/payByZhiFuBao")
    @ResponseBody
    public Result payByZhiFuBao(@RequestBody Map<String, Object> map) throws MySystemException {
        String orderSn = ObjectToOtherUtils.toString(map.get("orderSn"));
        BigDecimal amount = new BigDecimal((String) map.get("amount"));
        if (StringUtils.isBlank(orderSn)||amount==null){
            throw new MySystemException("参数异常", Constants.INVALID_PARM);
        }
        String html = myPay.pay(orderSn, amount.toString());
        return new Result().setCode(Constants.OK).setData(html).setMessage("操作成功");
    }

    /**
     * 支付验证
     * @param map
     * @return
     * @throws MySystemException
     */
    @RequestMapping("/payVerification")
    @ResponseBody
    public Result payVerification(@RequestBody Map<String, Object> map) throws MySystemException {
        String orderId = ObjectToOtherUtils.toString(map.get("orderId"));
        String orderSn = ObjectToOtherUtils.toString(map.get("orderSn"));
        if (StringUtils.isBlank(orderId)||StringUtils.isBlank(orderSn)){
            throw new MySystemException("参数异常", Constants.INVALID_PARM);
        }
        /** 验证订单是否支付--开始 **/
        Map<String, Object> paySucc = myPay.verificationPay(orderSn);
        if ((boolean)paySucc.get("succ")){
            /** 订单支付成功 -- 开始改变状态 **/
            ShopOrderInfo orderInfo = new ShopOrderInfo()
                    .setId(orderId)
                    .setOrderStatus(Constants.ORDER_STATUS_DELIVER)
                    .setPayTime(((Date)paySucc.get("payTime")).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
            /** 订单支付或收货接口 这里是支付 **/
            liShopOrderInfoService.orderPay(orderInfo);
        }
        return new Result().setCode(Constants.OK).setData(paySucc);
    }
    /**
     * 用户支付宝支付成功后回调
     * 第二版 集成支付宝
     * @param map
     * @return
     * @throws MySystemException
     */
    @RequestMapping("/pay")
    public Result orderPay(@RequestBody Map<String, Object> map) throws MySystemException {
        String orderSn = ObjectToOtherUtils.toString(map.get("orderSn"));
        String payTime = ObjectToOtherUtils.toString(map.get("payTime"));
        Integer orderStatus = ObjectToOtherUtils.toInteger(map.get("orderStatus"));
        /** 订单状态前端已经修改 **/
        if (StringUtils.isBlank(orderSn)||StringUtils.isBlank(payTime)||!Constants.ORDER_STATUS_DELIVER.equals(orderStatus)){
            throw new MySystemException("参数异常", Constants.INVALID_PARM);
        }
        UserElement userElement = getUserInfoByToken();
        String userId = userElement==null?null:userElement.getUserId();
        if (StringUtils.isBlank(userId)){
            throw new MySystemException("用户未登录",Constants.UNAUTHEN);
        }
        ShopOrderInfo orderInfoOfDB = liShopOrderInfoService.getOne(new QueryWrapper<>(new ShopOrderInfo().setOrderSn(orderSn).setUserId(userId)));
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        ShopOrderInfo orderInfo = new ShopOrderInfo()
                .setId(orderInfoOfDB.getId())
                .setOrderStatus(orderStatus)
                .setUserId(userId)
                .setPayTime(LocalDateTime.parse(payTime,df));
        /** 订单支付或收货接口 这里是支付 **/
        liShopOrderInfoService.orderPay(orderInfo);
        return new Result().setCode(Constants.OK).setData(orderInfo).setMessage("支付成功！");
    }


    /**
     * 消费者获取订单信息
     * @param map
     * @return
     */
    @RequestMapping("/listByPage")
    public Result getInfoPage(@RequestParam("page") Integer page, @RequestParam("size") Integer size, @RequestBody Map<String, Object> map) throws MySystemException {
        String userId = getUserInfoByToken().getUserId();
        if (StringUtils.isBlank(userId)){
            /** 用户ID为空 没有登陆 **/
            throw new MySystemException("没有登陆", Constants.UNAUTHEN);
        }
        /** 检查失效订单--开始 **/
        /** 获取未支付订单信息 **/
        List<ShopOrderInfo> payOrderInfos = liShopOrderInfoService.list(new QueryWrapper<>(new ShopOrderInfo().setUserId(userId).setOrderStatus(Constants.ORDER_STATUS_PAY)));
        if (CollectionUtils.isNotEmpty(payOrderInfos)){
            /** 未支付订单存在 **/
            /** 存储过期信息 **/
            List<ShopOrderInfo> cancelOrderInfos = new ArrayList<>();
            for (ShopOrderInfo payOrderInfo : payOrderInfos){
                /** 遍历未支付信息 **/
                /** 通过Redis查询订单是否过期 **/
                boolean overdue = cacheUtil.getCacheOrderPayCountDown(payOrderInfo.getId());
                if (!overdue){
                    /** 过期则存入过期列表里 **/
                    cancelOrderInfos.add(new ShopOrderInfo().setId(payOrderInfo.getId()).setOrderStatus(Constants.ORDER_STATUS_CANCEL));
//                    /** 更新订单状态 **/
//                    liShopOrderInfoService.updateById(new ShopOrderInfo().setId(payOrderInfo.getId()).setOrderStatus(Constants.ORDER_STATUS_CANCEL));
                }
            }
            if (CollectionUtils.isNotEmpty(cancelOrderInfos)){
                /** 过期列表不为空 则通过ID修改订单状态为取消 **/
                liShopOrderInfoService.updateBatchById(cancelOrderInfos);
            }
        }
        /** 检查失效订单--结束 **/
        /** 装配订单信息 **/
        ShopOrderInfo orderInfo = new ShopOrderInfo().setDelFlag(0);
        orderInfo.setUserId(userId);
        /** 装配Warpper **/
        List<String> orderStatusList = (List<String>) map.get("orderStatusList");
        if (CollectionUtils.isEmpty(orderStatusList)){
            /** 订单状态为空时 **/
            throw new MySystemException("请选择订单状态", Constants.INVALID_PARM);
        }
        /** 安状态查询时间降序查询 **/
        Wrapper<ShopOrderInfo> wrapper = new QueryWrapper<>(orderInfo).in("order_status", orderStatusList).orderByDesc("create_date");
        /** 分页查询 **/
        IPage<ShopOrderInfo> iPage = new Page<>(page, size);
        liShopOrderInfoService.page(iPage, wrapper);
        /** 获取订单信息 **/
        List<ShopOrderInfo> orderInfoDBs = iPage.getRecords();
        /** 重新存储数据 **/
        List<ShopOrderInfo> orderInfos = new ArrayList<>();
        /** 获取订单商品信息 **/
        for (ShopOrderInfo orderInfoDB : orderInfoDBs){
            List<ShopOrderGoods> orderGoodsList = iShopOrderGoodsService.list(new QueryWrapper<>(new ShopOrderGoods().setOrderId(orderInfoDB.getId())));
            orderInfoDB.setOrderGoods(orderGoodsList);
            orderInfos.add(orderInfoDB);
        }
        /** 重新装配数据 **/
        iPage.setRecords(orderInfos);
        return new Result().setCode(Constants.OK).setData(iPage);
    }

    /**
     * 管理员获取订单信息
     * @param map
     * @return
     */
    @RequestMapping("/infoByPage")
    public Result getOrderInfoPage(@RequestParam("page") Integer page, @RequestParam("size") Integer size, @RequestBody Map<String, Object> map) throws MySystemException {
        /** 装配Warpper **/
        /** 获取要查询的订单状态 **/
        List<String> orderStatusList = (List<String>) map.get("orderStatusList");
        if (CollectionUtils.isEmpty(orderStatusList)){
            /** 订单状态为空时 **/
            throw new MySystemException("请选择订单状态", Constants.INVALID_PARM);
        }
        /** 安状态查询时间降序查询 **/
        Wrapper<ShopOrderInfo> wrapper = new QueryWrapper<>(new ShopOrderInfo()).in("order_status", orderStatusList).orderByDesc("create_date");
        /** 装配要查询的订单号 **/
        String orderSn = ObjectToOtherUtils.toString(map.get("orderSn"));
        if (StringUtils.isNotBlank(orderSn)){
            ((QueryWrapper<ShopOrderInfo>) wrapper).like("order_sn", orderSn);
        }
        /** 装配筛选时间 **/
        List<String> createDate = (map.get("createDate")==null)?null: (map.get("createDate") instanceof Collection ? (List<String>) map.get("createDate"):null);
        if (CollectionUtils.isNotEmpty(createDate)){
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            ((QueryWrapper<ShopOrderInfo>) wrapper).between("create_date", LocalDateTime.parse(createDate.get(0),df),LocalDateTime.parse(createDate.get(1),df));
        }
        /** 装配需要查询的收货人电话 **/
        String phone = ObjectToOtherUtils.toString(map.get("phone"));
        /** 分页查询 **/
        IPage<ShopOrderInfo> iPage = new Page<>(page, size);
        liShopOrderInfoService.page(iPage, wrapper);
        /** 获取订单信息 **/
        List<ShopOrderInfo> orderInfoDBs = iPage.getRecords();
        /** 重新存储数据 **/
        List<ShopOrderInfo> orderInfos = new ArrayList<>();
        /** 获取订单商品信息和用户信息 **/
        for (ShopOrderInfo orderInfoDB : orderInfoDBs){
            /** 获取用户信息 **/
            ShopUser shopUser = userService.getById(orderInfoDB.getUserId());
            if (StringUtils.isBlank(phone)||(StringUtils.isNotBlank(phone)&&(shopUser.getPhone().indexOf(phone)!=-1))){
                /**手机号不存在，或者存在用户手机号包含上传的手机号 **/
                orderInfoDB.setShopUser(shopUser);
                /** 获取订单商品信息 **/
                List<ShopOrderGoods> orderGoodsList = iShopOrderGoodsService.list(new QueryWrapper<>(new ShopOrderGoods().setOrderId(orderInfoDB.getId())));
                orderInfoDB.setOrderGoods(orderGoodsList);
                orderInfos.add(orderInfoDB);
            }
        }
        /** 重新装配数据 **/
        iPage.setRecords(orderInfos);
        return new Result().setCode(Constants.OK).setData(iPage);
    }

    /**
     * 获取单个订单详细信息
     * @param map
     * @return
     */
    @RequestMapping("/infoById")
    public Result getOrderInfoOne(@RequestBody Map<String, Object> map) throws MySystemException {
        /** 装配Warpper **/
        String orderId = ObjectToOtherUtils.toString(map.get("id"));
        if (StringUtils.isBlank(orderId)){
            throw new MySystemException("参数异常", Constants.INVALID_PARM);
        }
        /** 获取订单信息 **/
        ShopOrderInfo orderInfo = liShopOrderInfoService.getById(orderId);
        List<ShopOrderGoods> orderGoodsList = iShopOrderGoodsService.list(new QueryWrapper<>(new ShopOrderGoods().setOrderId(orderId)));
        ShopUser user = userService.getById(orderInfo.getUserId());
        ShopOrderReturn orderReturn = orderReturnService.getOne(new QueryWrapper<>(new ShopOrderReturn().setOrderId(orderId)));
        orderInfo.setOrderGoods(orderGoodsList)
                .setShopUser(user)
                .setOrderReturn(orderReturn);
        return new Result().setCode(Constants.OK).setData(orderInfo).setMessage("获取订单信息成功");
    }

    /**
     * 管理员获取退货订单信息
     * @param map
     * @return
     */
    @RequestMapping("/infoOfReturnByPage")
    public Result getOrderReturnInfoPage(@RequestParam("page") Integer page, @RequestParam("size") Integer size, @RequestBody Map<String, Object> map) throws MySystemException {
        /** 装配Warpper **/
        /** 获取要查询的订单状态 **/
        List<String> orderStatusList = (List<String>) map.get("orderStatusList");
        if (CollectionUtils.isEmpty(orderStatusList)){
            /** 订单状态为空时 **/
            throw new MySystemException("请选择订单状态", Constants.INVALID_PARM);
        }
        /** 安状态查询 退货时间降序查询 **/
        Wrapper<ShopOrderInfo> wrapper = new QueryWrapper<>(new ShopOrderInfo()).in("order_status", orderStatusList).orderByDesc("applay_return_time");
        /** 装配要查询的订单号 **/
        String orderSn = ObjectToOtherUtils.toString(map.get("orderSn"));
        if (StringUtils.isNotBlank(orderSn)){
            ((QueryWrapper<ShopOrderInfo>) wrapper).like("order_sn", orderSn);
        }
        /** 装配筛选时间 **/
        List<String> createDate = (map.get("applayReturnTime")==null)?null: (map.get("applayReturnTime") instanceof Collection ? (List<String>) map.get("applayReturnTime"):null);
        if (CollectionUtils.isNotEmpty(createDate)){
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            ((QueryWrapper<ShopOrderInfo>) wrapper).between("applay_return_time", LocalDateTime.parse(createDate.get(0),df),LocalDateTime.parse(createDate.get(1),df));
        }
        /** 装配需要查询的收货人电话 **/
        String phone = ObjectToOtherUtils.toString(map.get("phone"));
        /** 分页查询 **/
        IPage<ShopOrderInfo> iPage = new Page<>(page, size);
        liShopOrderInfoService.page(iPage, wrapper);
        /** 获取订单信息 **/
        List<ShopOrderInfo> orderInfoDBs = iPage.getRecords();
        /** 重新存储数据 **/
        List<ShopOrderInfo> orderInfos = new ArrayList<>();
        /** 获取订单商品信息和用户信息 **/
        for (ShopOrderInfo orderInfoDB : orderInfoDBs){
            /** 获取用户信息 **/
            ShopUser shopUser = userService.getById(orderInfoDB.getUserId());
            if (StringUtils.isBlank(phone)||(StringUtils.isNotBlank(phone)&&(shopUser.getPhone().indexOf(phone)!=-1))){
                /**手机号不存在，或者存在用户手机号包含上传的手机号 **/
                orderInfoDB.setShopUser(shopUser);
                /** 获取订单商品信息 **/
                List<ShopOrderGoods> orderGoodsList = iShopOrderGoodsService.list(new QueryWrapper<>(new ShopOrderGoods().setOrderId(orderInfoDB.getId())));
                orderInfoDB.setOrderGoods(orderGoodsList);
                /** 装配退货信息 **/
                ShopOrderReturn orderReturn = orderReturnService.getOne(new QueryWrapper<>(new ShopOrderReturn().setOrderId(orderInfoDB.getId())));
                orderInfoDB.setOrderReturn(orderReturn);
                /** 装配订单信息 **/
                orderInfos.add(orderInfoDB);
            }
        }
        /** 重新装配数据 **/
        iPage.setRecords(orderInfos);
        return new Result().setCode(Constants.OK).setData(iPage);
    }

    /***
     * 订单退货成功或失败
     * @param map
     * @return
     * @throws MySystemException
     */
    @RequestMapping(value = "/returnProcessing")
    public Result returnProcessingSuccOrFail(@RequestBody Map<String, Object> map) throws MySystemException {
        String orderId = ObjectToOtherUtils.toString(map.get("id"));
        Integer orderStatus = ObjectToOtherUtils.toInteger(map.get("orderStatus"));
        if (StringUtils.isBlank(orderId)||orderStatus==null||(orderStatus!=90&&orderStatus!=95)){
            throw new MySystemException("参数异常", Constants.INVALID_PARM);
        }
        /** 更新订单状态 **/
        liShopOrderInfoService.returnProcessingSuccOrFail(orderId, orderStatus);
        return new Result().setCode(Constants.OK).setMessage("退货成功");
    }

}

